/**
 * @Creator: eyes
 * @Date: 2020/3/16
 * 「用户特征」模块-筛选条件表单: 状态管理.
 */
import {useReducer, useEffect, createContext} from 'react';

import {PERFORMANCE_TARGET_TYPE, TIME_DURATION} from '~/utils/const';
import {getFieldValues, getUserFeatureArea, getUserFeatureFields, getUserList} from '~/service/performance';
import {calcDateRangeStr, generateLatestWeek, generateUserListDateRange} from '../utils';
import {USER_FEATURE_ACTION_TYPES} from './utils';

export const StoreContext = createContext(null);

const getInitState = () => ({
    // 日期默认值: 最近七天.
    dateRange: generateLatestWeek(),
    selectedBusiness: null,
    businessList: [],
    businessScrollPage: 1,
    selectedApplication: null,
    applicationList: [],
    applicationScrollPage: 1,
    selectedPath: null,
    pathList: [],
    pathScrollPage: 1,

    // 以下为「更多筛选条件」里的备选项
    selectedProvince: [],
    selectedCarrier: [],
    selectedNetType: [],
    selectedOs: [],
    selectedOsVersion: [],
    selectedBrandVersion: [],

    // 以下存储用户特征查询结果

    // 用户清单状态管理，包含用户清单列表数据及分页信息
    userListData: {
        userListResult: [],
        pager: {
            pageNum: 1,
            pageSize: 10,
            count: 0,
        },
    },
    // 操作系统分布
    osSearchResult: [],
    // 操作系统版本分布
    osVersionSearchResult: [],
    // 机型分布
    brandVersionSearchResult: [],
    // 运营商分布
    carrierSearchResult: [],
    // 网络情况分布
    netTypeSearchResult: [],

    // 地域分布 [{province, pv, percent, userCityPvs: [{city, pv, percent}]}]
    areaSearchResult: [],
    // 地域分布地图中点击选中的省市
    selectedAreaMapProvince: [],
    // 地域分布的loading
    areaSearchLoading: false,

    // targetType状态
    targetType: PERFORMANCE_TARGET_TYPE.TTFP
});

const reducer = (state, action) => {
    const {type, payload = {}} = action;
    const {
        businessList,
        selectedAreaMapProvince,
    } = state;

    switch (type) {
        case USER_FEATURE_ACTION_TYPES.REGULAR_UPDATE:
            return {
                ...state,
                ...payload,
            };
        case USER_FEATURE_ACTION_TYPES.UPDATE_BUSINESS:
            return {
                ...state,
                selectedBusiness: payload.selectedBusiness,
                selectedApplication: null,
                applicationList: [],
                applicationScrollPage: 1,
                selectedPath: null,
                pathScrollPage: 1,
            };
        case USER_FEATURE_ACTION_TYPES.UPDATE_APPLICATION:
            return {
                ...state,
                selectedApplication: payload.selectedApplication,
                selectedPath: null,
                pathScrollPage: 1,
            };
        case USER_FEATURE_ACTION_TYPES.RESET:
            return {
                ...getInitState(),
                businessList,
            };
        case USER_FEATURE_ACTION_TYPES.SELECT_PROVINCE: {
            const {province} = payload;
            const newResult = selectedAreaMapProvince.includes(province)
                ? selectedAreaMapProvince.filter(_ => _ !== province)
                : [...selectedAreaMapProvince, province];
            return {
                ...state,
                selectedAreaMapProvince: newResult,
            };
        }
        default:
            return state;
    }
};

/**
 * API请求时转成参数格式. 对于操作系统类型/网络运营商这类备选筛选条件,
 * 只有有值时才作为参数传递, 如果是[]则不传递.
 * @param option 备选筛选条件. 比如操作系统类型
 * @returns {*}
 */
const transformOption = option => (
    option && option.length ? option : null
);
// 接下来会多次调用统一接口查询不同类型的数据, 接口参数大同小异.
// 此处统一定义基础参数, 后续主要添加field字段, 比如取值"carrier"则查询运营商数据
export const generateBasicParam = props => {
    const {
        dateRange,
        selectedBusiness,
        selectedApplication,
        selectedPath,
        levelType,
        selectedProvince,
        selectedCarrier,
        selectedNetType,
        selectedOs,
        selectedOsVersion,
        selectedBrandVersion,
        targetType
    } = props;
    // 此处的startTime, endTime按照服务端参数格式要求而计算
    const [startTime, endTime] = calcDateRangeStr(dateRange);
    return {
        targetType,
        levelType,
        bizTypeName: selectedBusiness,
        bizName: selectedApplication,
        path: selectedPath,
        startTime,
        endTime,
        province: transformOption(selectedProvince),
        carrier: transformOption(selectedCarrier),
        netType: transformOption(selectedNetType),
        os: transformOption(selectedOs),
        osVersion: transformOption(selectedOsVersion),
        brandVersion: transformOption(selectedBrandVersion),
    };
};
export const generateUserListParam = props =>
    ({...generateBasicParam(props), ...generateUserListDateRange(props.dateRange)});
export default props => {
    const {match: {params: {id}}} = props;
    // redux search, 需求：选择暂存
    const {searchParam} = props;
    const userFeatureParam = searchParam.userFeature;

    // 尽量不破坏原有结构, 未来可重构
    const [state, dispatch] = useReducer(reducer, {
        ...getInitState(),
        selectedBusiness: userFeatureParam.business,
        businessList: userFeatureParam.businessList,
        selectedApplication: userFeatureParam.project,
        applicationList: userFeatureParam.projectList,
        selectedPath: userFeatureParam.path,
        pathList: userFeatureParam.pathList,
        targetType: userFeatureParam.targetType,
        levelType: userFeatureParam.levelType
    });
    // 用户特征模块, 执行查询时的操作
    const onUserFeatureSearch = async () => {
        const basicParams = generateBasicParam(state);
        const userListParams = generateUserListParam(state);
        // 设置loading状态
        // osSelectedField代表下钻的状态，当点击查询时需要将osSelectedField置为空
        dispatch({
            type: USER_FEATURE_ACTION_TYPES.REGULAR_UPDATE,
            payload: {
                areaSearchLoading: true,
                userListLoading: true,
                osAndNetLoading: true,
                osSelectedField: ''
            },
        });

        // 查询地域分布
        const areaFeature = await getUserFeatureArea({
            ...basicParams,
            timeType: TIME_DURATION.ONE_DAY,
            pageId: id
        });

        dispatch({
            type: USER_FEATURE_ACTION_TYPES.REGULAR_UPDATE,
            payload: {
                areaSearchResult: areaFeature.data && areaFeature.data.userProvincePvs || [],
                areaSearchLoading: false,
            },
        });


        // 查询用户清单
        const userListData = await getUserList({...userListParams, pager: {pageNum: 1, pageSize: 10}});
        if (userListData?.data?.userDetails) {
            const data = userListData.data.userDetails.map((item, index) => ({
                ...item,
                key: `key${index}`
            }));

            dispatch({
                type: USER_FEATURE_ACTION_TYPES.REGULAR_UPDATE,
                payload: {
                    userListData: {
                        userListResult: data,
                        pager: userListData?.pager
                    },
                    userListLoading: false
                },
            });
        }

        // 同时查询: 查询操作系统总分布、系统版本top10、机型top10、运营商总分布、网络情况总分布
        const allFields = [
            {
                ...basicParams,
                field: 'os',
            },
            {
                ...basicParams,
                field: 'os_version',
                top: 10,
            },
            {
                ...basicParams,
                field: 'brand_version',
                top: 10,
            },
            {
                ...basicParams,
                field: 'carrier',
            },
            {
                ...basicParams,
                field: 'net_type',
            },
        ];

        const filedValues = await Promise.all(allFields.map(getUserFeatureFields));
        const toStore = [
            'osSearchResult',
            'osVersionSearchResult',
            'brandVersionSearchResult',
            'carrierSearchResult',
            'netTypeSearchResult',
        ]
            .reduce((result, key, index) => ({
                ...result,
                [key]: filedValues[index].data && filedValues[index].data.userFields || [],
            }), {});
        // 为各个表格数据加key属性，避免数据相同造成表格key不唯一报错
        for (const key in toStore) {
            if (key !== 'osSearchResult') {
                toStore[key] = toStore[key].map((item, index) => ({
                    ...item,
                    percent: `${item.percent}%`,
                    key: key.substring(0, 5) + index
                }));
            }
        }
        dispatch({
            type: USER_FEATURE_ACTION_TYPES.REGULAR_UPDATE,
            payload: {
                ...toStore,
                osAndNetLoading: false,
            },
        });

    };

    // 获取业务线列表
    useEffect(() => {
        (async () => {
            const {data: {values}} = await getFieldValues({
                field: 'biz_type_name',
            });
            dispatch({
                type: USER_FEATURE_ACTION_TYPES.REGULAR_UPDATE,
                payload: {
                    businessList: values,
                },
            });
        })();
    }, []);

    return [state, dispatch, StoreContext, onUserFeatureSearch];
};
